package com.aoip.telemetry.telemetry.configureui.business.analysis.stgroup.service.impl;

import com.aoip.telemetry.telemetry.configureui.business.analysis.group.mapper.ElementAnalysisGroupConfigMapper;
import com.aoip.telemetry.telemetry.configureui.business.analysis.stgroup.mapper.RelStAnalysisGroupConfigMapper;
import com.aoip.telemetry.telemetry.configureui.business.analysis.stgroup.service.StAnalysisGroupService;
import com.aoip.telemetry.telemetry.configureui.business.util.CommonMethod;
import com.aoip.telemetry.telemetry.core.redis.RedisCache;
import com.aoip.telemetry.telemetry.entity.element.ElementAnalysisGroupConfigEntity;
import com.aoip.telemetry.telemetry.entity.equipment.RelStAnalysisGroupConfigEntity;
import com.aoip.telemetry.telemetry.entity.enums.CacheKeyEnum;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenbai
 * @version 1.0
 * @date 2021/12/31 14:56
 */
@Service
@DS("telemetry")
public class StAnalysisGroupServiceImpl implements StAnalysisGroupService {

    @Resource
    private RelStAnalysisGroupConfigMapper mapper;

    @Resource
    private ElementAnalysisGroupConfigMapper elementAnalysisGroupMapper;

    @Resource
    private RedisCache redisCache;

    @Override
    public List<RelStAnalysisGroupConfigEntity> list(RelStAnalysisGroupConfigEntity entity) {
        return mapper.list(entity);
    }

    @Override
    public RelStAnalysisGroupConfigEntity stGroup(String id) {
        return mapper.selectById(id);
    }

    @Override
    public boolean checkStGroupExist(RelStAnalysisGroupConfigEntity entity) {
        QueryWrapper<RelStAnalysisGroupConfigEntity> queryWrapper = new QueryWrapper<>();
        String stCd = entity.getStCd();
        String funcCode = entity.getElementAnalysisGroupConfigEntity().getFuncCode();
        queryWrapper.eq("st_cd", stCd);
        queryWrapper.eq("func_code", funcCode);
        List<RelStAnalysisGroupConfigEntity> entityList = mapper.selectList(queryWrapper);
        if (entityList == null || entityList.size() == 0) {
            return false;
        }
        if (entityList.size() > 1) {
            return true;
        }
        RelStAnalysisGroupConfigEntity temp = entityList.get(0);
        return !temp.getId().equals(entity.getId());
    }

    @Override
    public List<ElementAnalysisGroupConfigEntity> analysisGroupListByStCd(String stCd) {
        QueryWrapper<RelStAnalysisGroupConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("st_cd", stCd);
        List<RelStAnalysisGroupConfigEntity> entityList = mapper.selectList(queryWrapper);
        List<String> groupIds = entityList.stream().map(RelStAnalysisGroupConfigEntity::getAnalysisGroupId).collect(Collectors.toList());
        if (groupIds.size() < 1) {
            return new ArrayList<>();
        }
        QueryWrapper<ElementAnalysisGroupConfigEntity> elementAnalysisGroupQueryWrapper = new QueryWrapper<>();
        elementAnalysisGroupQueryWrapper.in("id", groupIds);
        return elementAnalysisGroupMapper.selectList(elementAnalysisGroupQueryWrapper);
    }

    @Override
    public List<String> stCodesByGroupId(String groupId) {
        QueryWrapper<RelStAnalysisGroupConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("analysis_group_id", groupId);
        List<RelStAnalysisGroupConfigEntity> entityList = mapper.selectList(queryWrapper);
        return entityList.stream().map(RelStAnalysisGroupConfigEntity::getStCd).collect(Collectors.toList());
    }

    @Override
    public int insert(String stCd, List<String> groupIds) {
        if (groupIds == null) {
            return 1;
        }
        QueryWrapper<RelStAnalysisGroupConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("st_cd", stCd);
        List<RelStAnalysisGroupConfigEntity> entityList = mapper.selectList(queryWrapper);
        List<String> existGroupIds = new ArrayList<>();
        List<String> insertGroupIds = new ArrayList<>();
        entityList.forEach(item -> existGroupIds.add(item.getAnalysisGroupId()));

        collectCodes(groupIds, existGroupIds, insertGroupIds);
        insertGroupIds.forEach(item -> insertRelStGroup(stCd, item));
        existGroupIds.forEach(item -> delRelStGroup(stCd, item));
        int size = groupIds.size();
        return size == 0 ? 1 : size;
    }

    @Override
    public int insert(List<String> stCodes, String groupId) {
        if (stCodes == null) {
            return 1;
        }
        QueryWrapper<RelStAnalysisGroupConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("analysis_group_id", groupId);
        List<RelStAnalysisGroupConfigEntity> entityList = mapper.selectList(queryWrapper);
        List<String> existStCodes = new ArrayList<>();
        List<String> insertStCodes = new ArrayList<>();
        entityList.forEach(item -> existStCodes.add(item.getStCd()));

        collectCodes(stCodes, existStCodes, insertStCodes);
        insertStCodes.forEach(item -> insertRelStGroup(item, groupId));
        existStCodes.forEach(item -> delRelStGroup(item, groupId));
        int size = stCodes.size();
        return size == 0 ? 1 : size;
    }

    private void collectCodes(List<String> codes, List<String> existCodes, List<String> insertCodes) {
        for (String code : codes) {
            if (existCodes.contains(code)) {
                existCodes.remove(code);
                continue;
            }
            insertCodes.add(code);
        }
    }

    private void insertRelStGroup(String stCode, String groupId) {
        RelStAnalysisGroupConfigEntity entity = new RelStAnalysisGroupConfigEntity();
        entity.setStCd(stCode);
        entity.setAnalysisGroupId(groupId);
        redisCache.setCacheList(CacheKeyEnum.REL_ST_ANALYSIS_GROUP + ":" + stCode, groupId);
        mapper.insert(entity);
    }

    private void delRelStGroup(String stCode, String groupId) {
        QueryWrapper<RelStAnalysisGroupConfigEntity> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("st_cd", stCode);
        deleteWrapper.eq("analysis_group_id", groupId);
        redisCache.deleteObject(CacheKeyEnum.REL_ST_ANALYSIS_GROUP + ":" + stCode);
        mapper.delete(deleteWrapper);
    }

    @Override
    public int update(RelStAnalysisGroupConfigEntity entity) {
        return mapper.updateById(entity);
    }

    @Override
    public int initCache() {
        List<RelStAnalysisGroupConfigEntity> list = list(new RelStAnalysisGroupConfigEntity());
        Map<String, List<String>> map = new HashMap<>();
        list.forEach(item -> {
            String stCd = item.getStCd();
            String analysisGroupId = item.getAnalysisGroupId();
            CommonMethod.collectIdToMap(stCd, analysisGroupId, map);
        });
        Collection<String> keys = redisCache.keys(CacheKeyEnum.REL_ST_ANALYSIS_GROUP + ":*");
        redisCache.deleteObject(keys);
        map.forEach((key, val) -> redisCache.setCacheList(CacheKeyEnum.REL_ST_ANALYSIS_GROUP + ":" + key, val));
        return list.size();
    }

    @Override
    public void delete(long[] ids) {
        for (long id : ids) {
            RelStAnalysisGroupConfigEntity entity = mapper.selectById(id);
            redisCache.deleteObject(CacheKeyEnum.REL_ST_ANALYSIS_GROUP + ":" + entity.getStCd());
            mapper.deleteById(id);
        }
    }
}
